/************************************************************************/
/*    Author: Scott Bevin                                               */
/************************************************************************/

#include "GameScreenManagerComponent.h"

#include "GameScreen.h"
#include "../../XUtilities/Logger.h"

namespace XF
{
	GameScreenManagerComponent::GameScreenManagerComponent(Application *ownerApp) : 
		SystemComponent(ownerApp)
	{
	}

	GameScreenManagerComponent::~GameScreenManagerComponent()
	{
	}

	bool GameScreenManagerComponent::OnInitialise()
	{
		bool result =true;

		for(unsigned int i = 0; i < mGameScreens.size(); ++i)
		{
			result = (result && mGameScreens[i]->Initialise(this)); //chris i added in this check
		}

		return result;
	}

	void GameScreenManagerComponent::OnHandleInput(double dT, Input *input)
	{
		if(!mGameScreens.empty())
		{
			GameScreen *backScreen = mGameScreens.back();

			if(backScreen->GetScreenState() != ScreenState::SCREEN_NOT_ACTIVE)
				backScreen->HandleInput(dT, input);
		}
	}

	void GameScreenManagerComponent::OnUpdate(double dT)
	{
		GameScreen* oldTopScreen = mGameScreens[mGameScreens.size() - 1];

		for(unsigned int i = 0; i < mGameScreens.size(); ++i)
		{
			GameScreen* thisScreen = mGameScreens[i];

			if(thisScreen->ScreenWantsToExit() && thisScreen->GetScreenState() == ScreenState::SCREEN_NOT_ACTIVE)
			{
				thisScreen->Shutdown();

				mGameScreens.erase(mGameScreens.begin() + i);

				delete thisScreen;
			}
			else
			{
				thisScreen->Update(dT);
			}
		}

		if(oldTopScreen != mGameScreens[mGameScreens.size() - 1])
		{
			if(mGameScreens[mGameScreens.size() - 1]->GetScreenState() == ScreenState::SCREEN_NOT_ACTIVE)
			{
				int i = (int)mGameScreens.size();

				do 
				{
					--i;
					mGameScreens[i]->TransitionOn();
				} while (mGameScreens[i]->IsPopup() && i >= 0);
			}
		}
	}

	void GameScreenManagerComponent::OnShutDown()
	{
		for(unsigned int i = 0; i < mGameScreens.size(); ++i)
		{
			mGameScreens[i]->Shutdown();
			delete mGameScreens[i];
		}
	}

	void GameScreenManagerComponent::AddNewScreen(GameScreen* screen)
	{
		std::vector<GameScreen*>::iterator it = std::find(
			mGameScreens.begin(),
			mGameScreens.end(),
			screen);

		if(it == mGameScreens.end())
		{
			if(Initialised())
			{
				screen->Initialise(this);
			}
 
 			if(!screen->IsPopup())
 			{
 				for(unsigned int i = 0; i < mGameScreens.size(); ++i)
 				{
 					GameScreen* thisScreen = mGameScreens[i];
 
 					thisScreen->TransitionOff();
 				}
 			}

			mGameScreens.push_back(screen);
		}
		else
		{
			ILOG << "[GameScreenManagerComponent::AddNewScreen]: Attempted to add same screen instance more then once";
		}
	}

	void GameScreenManagerComponent::AddNewScreenUnderneathCurrentScreen( GameScreen* newScreen, GameScreen* currentScreen )
	{
		int idx = -1;

		for(unsigned int i = 0; i < mGameScreens.size(); ++i)
		{
			if(mGameScreens[i] == currentScreen)
			{
				idx = i;
			}

			if(mGameScreens[i] == newScreen)
			{
				ILOG << "[GameScreenManagerComponent::AddNewScreenUnderneathCurrentScreen]: Attempted to add same screen instance more then once";
			}
		}

		if(idx != -1)
		{
			mGameScreens.insert(mGameScreens.begin() + idx, newScreen);
		}
		else
		{
			ILOG << "[GameScreenManagerComponent::AddNewScreenUnderneathCurrentScreen]: Attempted to add screen under screent hat doesnt exist";
		}
	}

	void GameScreenManagerComponent::KillAllScreens()
	{
		for(unsigned int i = 0; i < mGameScreens.size(); ++i)
		{
			mGameScreens[i]->ExitScreen();
		}
	}
}
